package com.javalong.affairs.common;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;
import android.util.SparseArray;

public class UIHandler {

	private Handler handlerThread;
	private Handler handler;
	private SparseArray<List<ISynCallback>> mapCallback;

	private Integer nFlag = 10000;

	public UIHandler() {
		mapCallback = new SparseArray<List<ISynCallback>>();
		HandlerThread thread = new HandlerThread("thread");
		thread.start();
		Handler.Callback callback = new Handler.Callback() {

			@Override
			public boolean handleMessage(Message arg0) {
				Log.v("test", "sync:" + Thread.currentThread().getName() + ":"
						+ arg0.what);
				Bundle param = (Bundle) arg0.obj;
				if (mapCallback.indexOfKey(arg0.what) >= 0) {
					List<ISynCallback> list = mapCallback.get(arg0.what);
					Log.v("test", "sync:" + Thread.currentThread().getName()
							+ ":" + list);
					if (list != null) {
						for (ISynCallback callback : list) {
							if (callback != null)
								callback.OnSynCalled(arg0.what, param);
						}
					}
				}
				return false;
			};
		};
		handler = new Handler(callback);
		handlerThread = new Handler(thread.getLooper(), callback);
	}

	public void registerCallback(ISynCallback pCallback, int pulId) {
		List<ISynCallback> list = null;
		if (mapCallback.indexOfKey(pulId) > 0) {
			list = mapCallback.get(pulId);
			if (!list.contains(pCallback)) {
				list.add(pCallback);
			}
		} else {
			list = new ArrayList<ISynCallback>();
			list.add(pCallback);
			mapCallback.put(pulId, list);
		}
	}

	public void unRegisterCallback(ISynCallback pCallback, int ulId) {
		if (mapCallback.indexOfKey(ulId) != -1) {
			List<ISynCallback> list = mapCallback.get(ulId);
			if (list != null) {
				if (pCallback != null) {
					list.remove(pCallback);
				}
				if (list.isEmpty()) {
					mapCallback.remove(ulId);
				}
			}
		}
	}

	public void unRegisterCallback(int ulId) {
		if (mapCallback.indexOfKey(ulId) != -1) {
			mapCallback.get(ulId).clear();
			mapCallback.remove(ulId);
		}
	}

	public void postCallback(int ulId, Bundle param) {
		final Message msg = new Message();
		msg.what = ulId;
		msg.obj = param;
		handler.post(new Runnable() {
			@Override
			public void run() {
				handler.dispatchMessage(msg);
			}
		});
	}

	public void post(Runnable r) {
		handler.post(r);
	}

	public void postDelayed(Runnable r, long delayMillis) {
		handler.postDelayed(r, delayMillis);
	}

	public void sendCallback(int ulId, Bundle param) {
		Message msg = new Message();
		msg.what = ulId;
		msg.obj = param;
		handler.sendMessage(msg);
	}

	public class SimpleSynCallback implements ISynCallback {
		private Runnable action;

		public SimpleSynCallback(Runnable action) {
			this.action = action;
		}

		public void OnSynCalled(int ulID, Bundle param) {
			if (action != null) {
				action.run();
			}
			unRegisterCallback(ulID);
		}
	}

	public void postCallbackThread(int ulId, Bundle param) {
		final Message msg = new Message();
		msg.what = ulId;
		msg.obj = param;
		handlerThread.post(new Runnable() {
			@Override
			public void run() {
				handlerThread.dispatchMessage(msg);
			}
		});
	}

	public void postThread(Runnable r) {
		handlerThread.post(r);
	}

	public void postDelayedThread(Runnable r, long delayMillis) {
		handlerThread.postDelayed(r, delayMillis);
	}

	public void sendCallbackThread(int ulId, Bundle param) {
		Message msg = new Message();
		msg.what = ulId;
		msg.obj = param;
		handlerThread.sendMessage(msg);
	}

	public void runOnUiThread(Runnable action) {
		SimpleSynCallback callBack = new SimpleSynCallback(action);
		nFlag++;
		this.registerCallback(callBack, nFlag);
		this.sendCallback(nFlag, null);
	}
}